﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace calendar
{
public class ProjectCalendarWeek
{
    private string m_name;

    private DateRange m_dateRange;

    private ProjectCalendarWeek m_parent;

    private ProjectCalendarHours[] m_hours = new ProjectCalendarHours[7];

    private DayType[] m_days = new DayType[7];

    public static readonly DateRange DEFAULT_WORKING_MORNING = new DateRange(DateUtility.getTime(8,0), DateUtility.getTime(12,0));
    public static readonly DateRange DEFAULT_WORKING_AFTERNOON = new DateRange(DateUtility.getTime(13, 0), DateUtility.getTime(17,0));

    public ProjectCalendarWeek()
    {
        ///
    }
    public string Name
    {
        set {
            m_name = value;
        }

        get {
            return m_name;
        }
    }

    public DateRange DR
    {
        set {
            m_dateRange = value;
        }
        get {
            return m_dateRange;
        }
    }

    public ProjectCalendarWeek Parent
    {
        set {
            m_parent = value;

            setWorkingDay(Day.SUNDAY, DayType.DEFAULT);
            setWorkingDay(Day.MONDAY, DayType.DEFAULT);
            setWorkingDay(Day.TUESDAY, DayType.DEFAULT);
            setWorkingDay(Day.WEDNESDAY, DayType.DEFAULT);
            setWorkingDay(Day.THURSDAY, DayType.DEFAULT);
            setWorkingDay(Day.FRIDAY, DayType.DEFAULT);
            setWorkingDay(Day.SATURDAY, DayType.DEFAULT);
        }

        get {
            return m_parent;
        }
    }

    public bool isDerived()
    {
        return (m_parent != null);
    }

    public virtual ProjectCalendarHours addCalendarHours()
    {
        return (new ProjectCalendarHours(this));
    }

    public virtual ProjectCalendarHours addCalendarHours(Day day)
    {
        ProjectCalendarHours bch = new ProjectCalendarHours(this);
        bch.Day = day;
        m_hours[day.getValue() - 1] = bch;
        return bch;
    }

    public ProjectCalendarHours getCalendarHours(Day day)
    {
        return (m_hours[day.getValue() - 1]);
    }

    public ProjectCalendarHours[] getHours()
    {
        return m_hours;
    }

    public ProjectCalendarHours getHours(Day day)
    {
        ProjectCalendarHours result = getCalendarHours(day);
        if (result == null) {
            if (m_parent == null)
            {
                addDefaultCalendarHours(day);
                result = getCalendarHours(day);
            }
        } else {
            result = m_parent.getHours(day);
        }

        return result;
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="day"></param>
    public void addDefaultCalendarHours(Day day)
    {
        ProjectCalendarHours hours = addCalendarHours(day);
        if (day != Day.SATURDAY && day != Day.SUNDAY) {
            hours.addRange(DEFAULT_WORKING_MORNING);
            hours.addRange(DEFAULT_WORKING_AFTERNOON);
        }
    }

    public void addDefaultCalendarHours()
    {
        for (int i = 1; i <= 7; i++) {
            addDefaultCalendarHours(Day.getInstance(i));
        }
    }


    public virtual void attachHoursToDay(ProjectCalendarHours hours)
    {
        if (hours.ParentCalendar != this) {
            throw new NotImplementedException();
        }
        m_hours[hours.Day.getValue() - 1] = hours;
    }

    public virtual void removeHoursFromDay(ProjectCalendarHours hours)
    {
        if (hours.ParentCalendar != this) {
            throw new NotImplementedException();
        }
        m_hours[hours.Day.getValue() - 1] = null;
    }

    public DayType[] Days
    {
        get {
            return (m_days);
        }
    }

    public DayType getWorkingDay(Day day)
    {
        return (m_days[day.getValue() - 1]);
    }

    public void setWorkingDay(Day day, bool working)
    {
        DayType value = DayType.getInstance(working ? DayType.WORKING : DayType.NON_WORKING);
        setWorkingDay(day, value);
    }

    public void setWorkingDay(Day day, int value)
    {
        setWorkingDay(day, DayType.getInstance(value));
    }

    public void setWorkingDay(Day day, DayType working)
    {
        DayType value;
        if (working == null) {
            if (isDerived()) {
                value = DayType.getInstance(DayType.DEFAULT);
            } else {
                value = DayType.getInstance(DayType.WORKING);
            }
        } else {
            value = working;
        }

        m_days[day.getValue() - 1] = value;
    }
    
}
}
